package com.yorick.authority.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.yorick.authority.entitys.FindResourceDto;
import com.yorick.authority.entitys.ResourceDto;
import com.yorick.authority.entitys.Node;
import com.yorick.authority.modal.request.menu.MenuAddRequest;
import com.yorick.authority.modal.request.menu.MenuDetailRequest;
import com.yorick.authority.modal.request.menu.MenuEditRequest;
import com.yorick.authority.modal.request.menu.MenuListRequest;
import com.yorick.authority.modal.response.menu.MenuResponse;
import com.yorick.authority.service.AbstractAuthorityService;
import com.yorick.authority.service.MenuService;
import com.yorick.common.Result.SimpleFactory.ResultFactory;
import com.yorick.common.error.YorickAssert;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class MenuServiceImpl extends AbstractAuthorityService implements MenuService {


    @Override
    public List<JSONObject> menuList(MenuListRequest request) {
        List<ResourceDto> menus = menuMapper.findResources(request.isSuperRole());
        Map<Integer, Node> nodes = new HashMap<>();
        for (int i = 0; i < menus.size(); i++) {
            ResourceDto resourceDto = menus.get(i);
            //模拟数据库存储树结构
            Node node = Node.builder()
                    .id(resourceDto.getResourceId())
                    .parentId(resourceDto.getParentId())
                    .orderNum(resourceDto.getOrderNum())
                    .name(resourceDto.getResourceName())
                    .desc(resourceDto.getResourceDesc())
                    .enabled(resourceDto.getEnabled())
                    .build();
            nodes.put(i + 1, node);

        }
        List<JSONObject> menu = getNodeJson(0, nodes);
        return sortList(menu);
    }

    @Override
    public Map<String, Object> addMenu(MenuAddRequest request) {
        YorickAssert.validate(
                menuMapper.isResourceExist(request.getResourceName()) == 0,
                () -> "0",
                () -> "该模块已存在"
        );
        ResourceDto resourceDto = ResourceDto.builder()
                .resourceName(request.getResourceName())
                .resourceDesc(request.getResourceDesc())
                .resourceString(request.getResourceString())
                .parentId(request.getParentId())
                .build();
        resourceDto.setOrderNum(menuMapper.findOrderNumByResourceID(request.getParentId()));
        menuMapper.addResource(resourceDto);
        //清除mybatis缓存
        securityMapper.clearCache();
        return ResultFactory.success().display();
    }

    @Override
    public Map<String, Object> editMenu(MenuEditRequest request) {
        int isExist = menuMapper.isResourceExist(request.getResourceName());
        String resourceName = isExist > 0 ? StringUtils.EMPTY : request.getResourceName();

        ResourceDto resourceDto = ResourceDto.builder()
                .resourceId(request.getResourceId())
                .resourceName(resourceName)
                .resourceDesc(request.getResourceDesc())
                .resourceString(request.getResourceString())
                .enabled(request.getEnabled())
                .build();
        menuMapper.updateResource(resourceDto);
        //清除mybatis缓存
        securityMapper.clearCache();
        return ResultFactory.success().display();
    }

    @Override
    public ResourceDto menuDetail(MenuDetailRequest request) {
        FindResourceDto resourceDto = FindResourceDto.builder()
                .resourceId(request.getResourceId())
                .superRole(request.isSuperRole())
                .build();
        return menuMapper.findResourceByResourceID(resourceDto);
    }

    @Override
    protected JSONObject customizeNode(Node node) {
        MenuResponse response = MenuResponse.builder()
                .resourceId(node.getId())
                .resourceName(node.getName())
                .resourceDesc(node.getDesc())
                .orderNum(node.getOrderNum())
                .enabled(node.getEnabled())
                .build();

        return objectMapper.convertValue(response, JSONObject.class);
    }
}
